home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / ASTRONOM / H139.ZIP / UI101.ZIP / IO / UI / UI_LIST.C < prev    next >
C/C++ Source or Header  |  1991-11-04  |  38KB  |  1,384 lines

  1. /***************************************************************
  2.  
  3.     ui_list.c       List (Menu) Routines
  4.             for the Bywater Graphical User Interface
  5.  
  6.             Copyright (c) 1991, Ted A. Campbell
  7.  
  8.             Bywater Software
  9.             P. O. Box 4023 
  10.             Duke Station 
  11.             Durham, NC  27706
  12.  
  13.             email: tcamp@hercules.acpub.duke.edu
  14.  
  15.     Copyright and Permissions Information:
  16.  
  17.     All U.S. and international copyrights are claimed by the
  18.     author. The author grants permission to use this code
  19.     and software based on it under the following conditions:
  20.     (a) in general, the code and software based upon it may be 
  21.     used by individuals and by non-profit organizations; (b) it
  22.     may also be utilized by governmental agencies in any country,
  23.     with the exception of military agencies; (c) the code and/or
  24.     software based upon it may not be sold for a profit without
  25.     an explicit and specific permission from the author, except
  26.     that a minimal fee may be charged for media on which it is
  27.     copied, and for copying and handling; (d) the code must be 
  28.     distributed in the form in which it has been released by the
  29.     author; and (e) the code and software based upon it may not 
  30.     be used for illegal activities. 
  31.  
  32. ***************************************************************/
  33.  
  34. #include "stdio.h"
  35. #include "bw.h"
  36. #include "gr.h"
  37. #include "kb.h"
  38. #include "dr.h"
  39. #include "ui.h"
  40.  
  41. #define   EXTENSION  1         /* number of pixels to extend
  42.                            size of each menu item beyond
  43.                                 the height of the text */
  44. #define EL_OFFSET    1
  45. #define ACC          20
  46. #define SL_YSIZE     3
  47. #define SL_XMAX      18
  48.  
  49. /****************************************************************
  50.  
  51.    ui_ftext()   File selection -- text based
  52.  
  53. ****************************************************************/
  54.  
  55. ui_ftext( x1, y1, x2, y2, specifier, title, m_box,
  56.    d_titles, d_entries, max_entries,
  57.    background, foreground, highlight )
  58.    int x1, y1, x2, y2, background, foreground, highlight, max_entries;
  59.    struct menu_box *m_box;
  60.    char *specifier, *title;
  61.    char **d_titles;
  62.    struct dir_ent **d_entries;
  63.    {
  64.    register int number, c;
  65.  
  66.    /* First check for existence of the file */
  67.  
  68.    number = 0;
  69.    if ( dr_first( specifier, d_entries[ number ] ) == FALSE )
  70.       {
  71.       return FALSE;
  72.       }
  73.    strcpy( d_titles[ number ], d_entries[ number ]->filename );
  74.  
  75.    /* Find all entries */
  76.  
  77.    number = 1;
  78.    while( ( dr_next( d_entries[ number ] ) == TRUE ) && ( number < max_entries ))
  79.       {
  80.       strcpy( d_titles[ number ], d_entries[ number ]->filename );
  81.       ++number;
  82.       }
  83.    m_box->number = number;
  84.  
  85.    m_box->d_titles = d_titles;
  86.    m_box->d_entries = d_entries;
  87.    m_box->max_entries = max_entries;
  88.  
  89.    /* menu */ 
  90.  
  91.    c = ui_list( MENU_SLIDERS, x1, y1, x2, y2,
  92.       title, number, d_titles, foreground, background, highlight,
  93.       m_box, TRUE );
  94.  
  95.    return c;
  96.  
  97.    }
  98.  
  99. /****************************************************************
  100.  
  101.    ui_list()   Scrolling list (menu)
  102.  
  103. ****************************************************************/
  104.  
  105. ui_list( type, x1, y1, x2, y2, title, number, titles,
  106.    foreground, background, highlight, m_box )
  107.    int type, x1, y1, x2, y2, foreground, background,
  108.       highlight, number;
  109.    char *title;
  110.    char **titles;
  111.    struct menu_box *m_box;
  112.    {
  113.    int carry_on;
  114.    static int c, test;
  115.    int mo_xsrc, mo_ysrc;
  116.    static int x_pos, y_pos, b_stat, item;
  117.  
  118.    /* draw the list */
  119.  
  120.    uil_draw( type, x1, y1, x2, y2, title, number, titles,
  121.       foreground, background, highlight, m_box );
  122.  
  123.    /* activate the list */
  124.  
  125.    uil_activate( m_box, type, 0 );
  126.  
  127.    /* poll while waiting for keyboard or mouse input, carry_on == TRUE */
  128.  
  129.    test = FALSE;
  130.    carry_on = TRUE;
  131.    while( carry_on == TRUE )
  132.       {
  133.       if ( kb_rxstat() == TRUE )
  134.      {
  135.      c = kb_rx();
  136.      test = TRUE;
  137.      }
  138.       else if ( gr_ismouse == TRUE )
  139.      {
  140.      if ( gr_mouse( SAMPLE, &x_pos, &y_pos, &b_stat )
  141.         == TRUE )
  142.         {
  143.         c = 0;
  144.         test = TRUE;
  145.         gr_mouse( WAIT, &x_pos, &y_pos, &b_stat );
  146.         mo_xsrc = x_pos;
  147.         mo_ysrc = y_pos;
  148.         gr_mouse( WAIT, &x_pos, &y_pos, &b_stat );
  149.         }
  150.      }
  151.  
  152.       if ( test == TRUE )
  153.      {
  154. #ifdef  OLD_DEBUG
  155.      bw_error( "ready to call uil_event()" );
  156. #endif
  157.      c = uil_event( m_box, c, mo_xsrc, mo_ysrc, x_pos, y_pos, type,
  158.         &item );
  159.      switch( c )
  160.         {
  161.         case EVENT_SELECTED:
  162.            carry_on = FALSE;
  163.            break;
  164.         case EVENT_EXIT:
  165.            item = TK_EXIT;
  166.            carry_on = FALSE;
  167.            break;
  168.         case EVENT_ERROR:
  169.            bw_error( "Error return from uil_event()" );
  170.            carry_on = FALSE;
  171.            break;
  172.         case EVENT_NULL:
  173.         default:
  174.            test = FALSE;
  175.            break;
  176.         }
  177.      }
  178.  
  179.       ui_poll();
  180.  
  181.       }                         /* end of main list loop */
  182.  
  183. #ifdef  OLD_DEBUG
  184.    bw_error( "Ready to deactivate list box" );
  185. #endif
  186.  
  187.    uil_deactivate( m_box, type );
  188.  
  189. #ifdef  OLD_DEBUG
  190.    bw_error( "List box deactivated" );
  191. #endif
  192.  
  193.    return item;
  194.  
  195.    }
  196.  
  197. /****************************************************************
  198.  
  199.     uil_draw() - draw a list box
  200.  
  201. ****************************************************************/
  202.  
  203. uil_draw( type, x1, y1, x2, y2, title, number, titles,
  204.    foreground, background, highlight, m_box )
  205.    int type, x1, y1, x2, y2, foreground, background,
  206.       highlight, number;
  207.    char *title;
  208.    char **titles;
  209.    struct menu_box *m_box;
  210.    {
  211.    register int y;
  212.  
  213. #ifdef    OLD_DEBUG
  214.    ui_debug( "entered uil_draw()" );
  215. #endif
  216.  
  217.    /* initial assignments */
  218.  
  219.    m_box->current = 0;
  220.    m_box->x_pos = m_box->y_pos = m_box->y_start = 0;
  221.    m_box->y_logical = m_box->number = number;
  222.    m_box->x_items = m_box->x_logical = 1;
  223.    m_box->ysize = ui_grwind->fysize + EXTENSION;
  224.    m_box->type = type;
  225.    m_box->d_titles = titles;
  226.    m_box->x_start = 0;
  227.    
  228.    if ( m_box->is_drawn == FALSE )
  229.       {
  230.  
  231.       /* assign colors to structure */
  232.  
  233.       m_box->fore = foreground;
  234.       m_box->back = background;
  235.       m_box->high = highlight;
  236.  
  237.       /* draw the menu window */
  238.  
  239.       if ( m_box->window == NULL )
  240.          {
  241.          switch( m_box->type )
  242.             {
  243.  
  244.             case MENU_SLIDERS:
  245. #ifdef OLD_DEBUG
  246.                sprintf( bw_ebuf, "make slider window %d %d %d %d", 
  247.                   x1, y1, x2, y2 );
  248.                bw_debug( bw_ebuf );
  249. #endif
  250.            m_box->window = ui_window( x1, y1,
  251.                   x2, y2, TRUE, 
  252.                   highlight, foreground,
  253.                   title, TRUE, BLACK, 
  254.                   FALSE, BLACK, background, 
  255.           SOLID, BUT_CLOSE | BUT_MOVE | BUT_RESIZE );
  256. #ifdef OLD_DEBUG
  257.                sprintf( bw_ebuf, "made slider window %d %d %d %d", 
  258.                   m_box->window->x1, m_box->window->y1, m_box->window->x2, m_box->window->y2 );
  259.                bw_debug( bw_ebuf );
  260. #endif
  261.                break;
  262.  
  263.             case MENU_TITLED:
  264.                y = ( m_box->y_logical * m_box->ysize )
  265.           + ( ui_grwind->fysize * 3 );
  266.            m_box->window = ui_window( x1, y2 - y,
  267.                   x2, y2, TRUE, 
  268.                   highlight, foreground,
  269.                   title, TRUE, BLACK, 
  270.                   TRUE, BLACK, background, 
  271.           SOLID, BUT_CLOSE | BUT_MOVE | BUT_RESIZE  );
  272.                break;
  273.  
  274.             case MENU_PLAIN:
  275.             default:
  276.  
  277.  
  278. #ifdef    OLD_DEBUG
  279.    sprintf( ui_tbuf, "called uil_draw(): %d %d %d %d (xmax %d) (ymax %d)",
  280.       x1, y2 - y, 
  281.           x2, y2, ui_grwind->xmax, ui_grwind->ymax );
  282.    ui_debug( ui_tbuf );
  283. #endif
  284.  
  285.                y = ( m_box->y_logical * m_box->ysize )
  286.           + ( ui_grwind->fysize );
  287.            m_box->window = ui_window( x1, y2 - y,
  288.                   x2, y2, FALSE,
  289.                   background, foreground,
  290.                   title, FALSE, BLACK, 
  291.                   TRUE, BLACK, background, 
  292.           SOLID, 0 );
  293.                break;
  294.             }
  295.          }
  296.  
  297.       else
  298.          {
  299.      ui_rewindow( m_box->window, title );
  300.          }
  301.  
  302.       /* display the menu */
  303.  
  304.       uil_display( m_box );
  305.  
  306.       }
  307.    }
  308.  
  309. /****************************************************************
  310.  
  311.    uil_activate()   Activate a list box
  312.  
  313. ****************************************************************/
  314.  
  315. uil_activate( m_box, type, item )
  316.    struct menu_box *m_box;
  317.    int type, item;
  318.    {
  319.    register int x, y;
  320.    int carry_on;
  321.    
  322. #ifdef    DEBUG
  323.    if ( m_box->d_titles == NULL )
  324.       {
  325.       bw_error( "Programmer error: menu box has not been drawn!" );
  326.       return FALSE;
  327.       }
  328. #endif
  329.  
  330.    if ( item > m_box->number )
  331.       {
  332.       item = 0;
  333.       }
  334.  
  335.    if ( item == 0 )
  336.       {
  337.       m_box->x_start = m_box->y_start = m_box->x_pos = m_box->y_pos
  338.          = m_box->current = 0;
  339.       }
  340.    else if ( item != m_box->current )
  341.       {
  342.  
  343.       m_box->current = item;
  344.       
  345.       /* calculate y_start */
  346.  
  347.       y = 0;
  348.       carry_on = TRUE;
  349.       if ( m_box->y_logical <= m_box->y_items )
  350.          {
  351.          y = 0;
  352.          }
  353.       else while( ( y < m_box->y_logical ) && ( carry_on == TRUE ))
  354.          {
  355.          if ( (( m_box->x_logical * y ) +
  356.             ( m_box->x_logical * m_box->y_items )) > item )
  357.             {
  358.             carry_on = FALSE;
  359.             }
  360.          else
  361.             {
  362.             ++y;
  363.             }
  364.          }
  365.  
  366.       /* calculate x_start */
  367.  
  368.       x = 0;
  369.       carry_on = TRUE;
  370.       if ( m_box->x_logical <= m_box->x_items )
  371.          {
  372.          x = 0;
  373.  
  374. #ifdef OLD_DEBUG
  375.       sprintf( ui_tbuf, "x_logical <= x_items" );
  376.       ui_wtitle( m_box->window, ui_tbuf );
  377.       ui_wait();
  378. #endif
  379.          }
  380.       else while( ( x < m_box->x_logical ) && ( carry_on == TRUE ))
  381.          {
  382.  
  383. #ifdef OLD_DEUG
  384.       sprintf( ui_tbuf, "item <> x_logical = %d",  item % m_box->x_logical );
  385.       ui_wtitle( m_box->window, ui_tbuf );
  386.       ui_wait();
  387.       
  388.       sprintf( ui_tbuf, "trying %d", x );
  389.       ui_wtitle( m_box->window, ui_tbuf );
  390.       ui_wait();
  391. #endif
  392.  
  393.          if (( m_box->x_items + x ) > ( item % m_box->x_logical ))
  394.             {
  395.             carry_on = FALSE;
  396.             }
  397.          else
  398.             {
  399.             ++x;
  400.             }
  401.          }
  402.  
  403. #ifdef OLD_DEBUG
  404.       sprintf( ui_tbuf, "i %d; x %d; y %d", item, x, y );
  405.       ui_wtitle( m_box->window, ui_tbuf );
  406. #endif
  407.  
  408.       m_box->y_start = y;
  409.       m_box->x_start = x;
  410.       m_box->y_pos = ( item / m_box->x_logical ) - m_box->y_start;
  411.       m_box->x_pos = ( item % m_box->x_logical ) - m_box->x_start;
  412.  
  413.       uil_display( m_box );
  414.       }
  415.  
  416.    /* display the exit button */
  417.  
  418.    if ( type != MENU_PLAIN )
  419.       {
  420. #ifdef USE_ICONS
  421. #else
  422.       ui_fbox( m_box->window->bt_x1, m_box->window->bt_y1,
  423.      m_box->window->bt_x2, m_box->window->bt_y2, BLACK, SOLID );
  424.       ui_fbox( m_box->window->bt_x1 + 1, m_box->window->bt_y1 + 1,
  425.      m_box->window->bt_x2 - 1, m_box->window->bt_y2 - 1, WHITE, GRID );
  426. #endif
  427.       }
  428.  
  429.    /* show current item selected */
  430.  
  431.    uil_item( m_box, m_box->current,
  432.       m_box->d_titles[ m_box->current ], TRUE );
  433.  
  434.    }
  435.  
  436. /****************************************************************
  437.  
  438.    uil_deactivate()   Deactivate a list menu box
  439.  
  440. ****************************************************************/
  441.  
  442. uil_deactivate( m_box, type )
  443.    struct menu_box *m_box;
  444.    int type;
  445.    {
  446.  
  447. #ifdef  OLD_DEBUG
  448.    bw_error( "enter deactivate" );
  449. #endif
  450.  
  451.    uil_item( m_box, m_box->current,
  452.       m_box->d_titles[ m_box->current ], FALSE );
  453.  
  454. #ifdef  OLD_DEBUG
  455.    bw_error( "exit deactivate" );
  456. #endif
  457.  
  458.    }
  459.  
  460. /****************************************************************
  461.  
  462.    uil_event()   Query if an event affects a list box
  463.  
  464. ****************************************************************/
  465.  
  466. uil_event( m_box, key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest, type, item )
  467.    struct menu_box *m_box;
  468.    int key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest, type;
  469.    int *item;
  470.    {
  471.    static int how_far, x_sel, y_sel;
  472.    register int c;
  473.  
  474.    how_far = 0;
  475.    c = ui_event( m_box, key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest,
  476.       &how_far, &x_sel, &y_sel );
  477.  
  478.    switch( c )
  479.       {
  480.  
  481.       case FALSE:
  482.          *item = TK_EXIT;
  483.          return EVENT_NULL;
  484.  
  485.       case CR:
  486.       case LF:
  487.      uil_exit( m_box, type );
  488.          *item = m_box->current;
  489.          return EVENT_SELECTED;
  490.          break;
  491.  
  492.       case KB_DOWN:
  493.          if ( m_box->current < ( m_box->number - 1 ))
  494.             {
  495.         uil_item( m_box, m_box->current,
  496.                m_box->d_titles[ m_box->current ],
  497.                FALSE );
  498.             ++m_box->current;
  499.             ++m_box->y_pos;
  500.             if ( m_box->y_pos == m_box->y_items )
  501.                {
  502.                ++m_box->y_start;
  503.                --m_box->y_pos;
  504.            uil_display( m_box );
  505.            uil_item( m_box, m_box->current,
  506.                   m_box->d_titles[ m_box->current ],
  507.                   TRUE );
  508.                }
  509.             else
  510.                {
  511.            uil_item( m_box, m_box->current,
  512.                   m_box->d_titles[ m_box->current ],
  513.                   TRUE );
  514.                }
  515.             }
  516.          *item = 0;
  517.          return EVENT_NULL;
  518.          break;
  519.  
  520.       case KB_UP:
  521.          if ( m_box->current > 0 )
  522.             {
  523.         uil_item( m_box, m_box->current,
  524.                m_box->d_titles[ m_box->current ],
  525.                FALSE );
  526.             --m_box->current;
  527.             --m_box->y_pos;
  528.             if ( ( m_box->y_start > 0  ) && ( m_box->y_pos < 0 ))
  529.                {
  530.                --m_box->y_start;
  531.                ++m_box->y_pos;
  532.            uil_display( m_box );
  533.            uil_item( m_box, m_box->current,
  534.                   m_box->d_titles[ m_box->current ],
  535.                   TRUE );
  536.                }
  537.             else
  538.                {
  539.            uil_item( m_box, m_box->current,
  540.                   m_box->d_titles[ m_box->current ],
  541.                   TRUE ); 
  542.                }
  543.             }
  544.          *item = 0;
  545.          return EVENT_NULL;
  546.          break;
  547.  
  548.       case ESCAPE:
  549.       case MO_EXIT:
  550.      uil_exit( m_box, type );
  551.          *item = 0;
  552.          return TK_EXIT;
  553.          break;
  554.  
  555.       case MO_UP:
  556.          if ( m_box->y_start > 0 )
  557.             {
  558.             while ( ( m_box->y_start - how_far ) < 0 )
  559.                {
  560.                --how_far;
  561.                }
  562.             m_box->y_start -= how_far;
  563.             m_box->current -= how_far;
  564.         uil_display( m_box );
  565.         uil_item( m_box, m_box->current,
  566.                m_box->d_titles[ m_box->current ],
  567.                TRUE );
  568.             }
  569.          *item = 0;
  570.          return EVENT_NULL;
  571.          break;
  572.  
  573.       case MO_DN:
  574.          if ( ( m_box->y_start + m_box->y_items )
  575.             < m_box->number )
  576.             {
  577.             while ( ( m_box->y_start + how_far + m_box->y_items )
  578.                > m_box->number )
  579.                {
  580.                --how_far;
  581.                }
  582.             m_box->y_start += how_far;
  583.             m_box->current += how_far;
  584.         uil_display( m_box );
  585.         uil_item( m_box, m_box->current,
  586.                m_box->d_titles[ m_box->current ],
  587.                TRUE );
  588.             }
  589.          *item = 0;
  590.          return EVENT_NULL;
  591.          break;            
  592.  
  593.       case MO_SEL:
  594.           if ( y_sel == m_box->y_pos )
  595.                {
  596.            uil_exit( m_box, type );
  597.                *item = m_box->current;
  598.                return EVENT_SELECTED;
  599.                }
  600.         uil_item( m_box, m_box->current,
  601.                m_box->d_titles[ m_box->current ], FALSE );
  602.             m_box->current = m_box->y_start + y_sel;
  603.             m_box->y_pos = y_sel;
  604.         uil_item( m_box, m_box->current,
  605.                m_box->d_titles[ m_box->current ], TRUE );
  606.             *item = 0;
  607.             return EVENT_NULL;
  608.             break;
  609.  
  610.          default:
  611.             *item = 0;
  612.             return EVENT_NULL;
  613.             break;
  614.       }
  615.    }
  616.  
  617. /****************************************************************
  618.  
  619.    uil_display()   Show all items in a list box
  620.  
  621. ****************************************************************/
  622.  
  623. uil_display( m_box )
  624.    struct menu_box *m_box;
  625.    {
  626.    register int c, v;
  627.    int x, y;
  628.  
  629.    if ( m_box->is_drawn == FALSE )
  630.       {
  631.       switch( m_box->type )
  632.          {
  633.          case MENU_SLIDERS:
  634.             uil_sliders( m_box );
  635.             break;
  636.          case MENU_TITLED:
  637.          case MENU_PLAIN:
  638.          default:
  639.         uil_plain( m_box );
  640.             break;
  641.          }
  642.       }
  643.  
  644.    /* calculate visible lines */
  645.  
  646.    m_box->y_items = ( m_box->i_y2 - m_box->i_y1 )
  647.       / m_box->ysize;
  648.    m_box->xsize = ( m_box->i_x2 - m_box->i_x1 ) / m_box->x_logical;
  649.  
  650.    if ( m_box->type == MENU_SLIDERS )
  651.       {
  652.  
  653.       /* calculate increments for elevators */
  654.    
  655.       x = ui_grwind->ymax / 15;
  656.       y = ( x * gr_pxsize ) / gr_pysize;
  657.    
  658.       if ( m_box->y_logical <= m_box->y_items )
  659.          {
  660.          m_box->vel_inc = 1;
  661.          }
  662.       else
  663.          {
  664.          m_box->vel_inc = ((( m_box->ve_y2 - ( m_box->ve_y1 + y )) 
  665.             * INC_ACCURACY )
  666.             / ( m_box->y_logical - m_box->y_items ));
  667.          }
  668.    
  669.       if ( m_box->vel_inc <= 0 )      /* increment cannot be <= 0 */
  670.          {
  671.          m_box->vel_inc = 1;
  672.          }
  673.    
  674.       if ( m_box->x_logical <= m_box->x_items )
  675.          {
  676.          m_box->hel_inc = 1;
  677.          }
  678.       else
  679.          {
  680.          m_box->hel_inc = ((( m_box->he_x2 - ( m_box->he_x1 + x ))
  681.             * INC_ACCURACY )
  682.             / ( m_box->x_logical - m_box->x_items ));
  683.          }
  684.    
  685.       if ( m_box->vel_inc <= 0 )      /* increment cannot be <= 0 */
  686.          {
  687.          m_box->vel_inc = 1;
  688.          }
  689.    
  690.       uil_vel( m_box );              /* show vertical elevator */
  691.       if ( m_box->is_drawn == FALSE )
  692.          {
  693.      uil_hel( m_box );            /* show horizontal elevator */
  694.          }
  695.       }
  696.  
  697.    c = 0;
  698.    v = m_box->y_start;
  699.    while ( ( c < m_box->y_items ) && ( v < m_box->number ))
  700.       {
  701.  
  702.       uil_item( m_box, v, m_box->d_titles[ v ], FALSE );
  703.       ++c;
  704.       ++v;
  705.       }
  706.  
  707.    m_box->is_drawn = TRUE;
  708.  
  709.    }
  710.  
  711. /****************************************************************
  712.  
  713.    uil_item()   Show a particular item in a list box
  714.  
  715. ****************************************************************/
  716.  
  717. uil_item( m_box, item, text, selected )
  718.    struct menu_box *m_box;
  719.    int item, selected;
  720.    char *text;
  721.    {
  722.    int x1, y1, x2, y2;
  723.  
  724.    x1 = m_box->i_x1;
  725.    y1 = m_box->i_y2 - ( m_box->ysize *
  726.       ( 1 + item - m_box->y_start ));
  727.    x2 = m_box->i_x2;
  728.    y2 = m_box->i_y2 - ( m_box->ysize *
  729.       ( item - m_box->y_start ));
  730.  
  731.    if ( selected == TRUE )
  732.       {
  733.       ui_fbox( x1, y1, x2, y2, m_box->fore, SOLID );
  734.       ui_str( x1, y1 + EXTENSION, x2, m_box->fore, m_box->back,
  735.          text );
  736.       }
  737.    else
  738.       {
  739.       ui_fbox( x1, y1, x2, y2, m_box->back, SOLID );
  740.       ui_str( x1, y1 + EXTENSION, x2, m_box->back, m_box->fore,
  741.          text );
  742.       }
  743.    }
  744.  
  745. /****************************************************************
  746.  
  747.    uil_vel()   Show vertical elevator
  748.  
  749. ****************************************************************/
  750.  
  751. uil_vel( m_box )
  752.    struct menu_box *m_box;
  753.    {
  754.    int y_pos;
  755.  
  756.    /* return if no area (box too small ) */
  757.  
  758.    if ( m_box->ve_y2 <= m_box->ve_y1 )
  759.       {
  760. #ifdef OLD_DEBUG
  761.       bw_debug( "No room for vertical slider" );
  762. #endif
  763.       return FALSE;
  764.       }
  765.    
  766. #ifdef OLD_DEBUG
  767.    bw_debug( "Drawing vertical slider" );
  768. #endif
  769.  
  770.    /* first blank the elevator area */
  771.  
  772.    ui_fbox( m_box->vs_x1, m_box->ve_y1, m_box->vs_x2, m_box->ve_y2,
  773.       BLACK, SOLID );
  774.    ui_fbox( m_box->vs_x1 + 1, m_box->ve_y1 + 1,
  775.       m_box->vs_x2 - 1, m_box->ve_y2 - 1,
  776.       m_box->back, GRID );
  777.  
  778.    /* calculate size and current position */
  779.  
  780.    y_pos = m_box->ve_y2 - (( m_box->y_start * m_box->vel_inc ) / INC_ACCURACY );
  781.  
  782.    m_box->vel_y1 = y_pos - ( m_box->ve_y1 - m_box->vs_y1 );
  783.    m_box->vel_x1 = m_box->vs_x1;
  784.    m_box->vel_x2 = m_box->vs_x2;
  785.    m_box->vel_y2 = y_pos;
  786.  
  787. #ifdef  OLD_DEBUG
  788.    sprintf( bw_ebuf, "vel y1 %d   y2 %d   y_pos %d",
  789.       m_box->vel_y1, m_box->vel_y2, y_pos );
  790.    bw_debug( bw_ebuf );
  791. #endif
  792.  
  793.    /* draw the elevator */
  794.  
  795. #ifdef USE_ICONS
  796.    ui_pbmcenter( ui_screen, m_box->vel_x1, m_box->vel_y1, m_box->vel_x2,
  797.       m_box->vel_y2, &ui_elicon );
  798. #else
  799.    ui_fbox( m_box->vel_x1 + EL_OFFSET, m_box->vel_y1 + EL_OFFSET,
  800.       m_box->vel_x2 - EL_OFFSET, m_box->vel_y2 - EL_OFFSET,
  801.       BLACK, SOLID );
  802.    ui_fbox( m_box->vel_x1 + EL_OFFSET + 1,
  803.       m_box->vel_y1 + EL_OFFSET + 1,
  804.       m_box->vel_x2 - ( EL_OFFSET + 1 ),
  805.       m_box->vel_y2 - ( EL_OFFSET + 1 ),
  806.       m_box->back, SOLID );
  807.    gr_circle( ui_screen,
  808.       m_box->vel_x1 + (( m_box->vel_x2 - m_box->vel_x1 ) / 2 ),
  809.       m_box->vel_y1 + ( ( m_box->ve_y1 - m_box->vs_y1 ) / 2 ),
  810.       ( m_box->ve_y1 - m_box->vs_y1 ) / 4, BLACK, SOLID );
  811.    gr_circle( ui_screen,
  812.       m_box->vel_x1 + (( m_box->vel_x2 - m_box->vel_x1 ) / 2 ),
  813.       m_box->vel_y1 + ( ( m_box->ve_y1 - m_box->vs_y1 ) / 2 ),
  814.       ( m_box->ve_y1 - m_box->vs_y1 ) / 4, m_box->high, GRID );
  815. #endif
  816.    }
  817.  
  818. /****************************************************************
  819.  
  820.    uil_hel()   Show horizontal elevator
  821.  
  822. ****************************************************************/
  823.  
  824. uil_hel( m_box )
  825.    struct menu_box *m_box;
  826.    {
  827.    int x_pos;
  828.  
  829.    /* first blank the elevator area */
  830.  
  831.    ui_fbox( m_box->he_x1, m_box->hs_y1,
  832.       m_box->he_x2, m_box->hs_y2,
  833.       BLACK, SOLID );
  834.    ui_fbox( m_box->he_x1 + 1, m_box->hs_y1,
  835.       m_box->he_x2 - 1, m_box->hs_y2,
  836.       m_box->back, GRID );
  837.  
  838.    /* calculate size and current position */
  839.  
  840.    m_box->hel_x1 = x_pos = m_box->he_x1 
  841.       + (( m_box->hel_inc * m_box->x_start ) / INC_ACCURACY );
  842.    m_box->hel_x2 = m_box->hel_x1 + ( m_box->hs_x2 - m_box->he_x2 );
  843.    m_box->hel_y1 = m_box->hs_y1;
  844.    m_box->hel_y2 = m_box->hs_y2;
  845.  
  846. #ifdef  OLD_DEBUG
  847.    sprintf( ui_tbuf, "he_x1 = %d, inc * start = %d, inc = %d, start = %d, x_pos = %d, hel = %d",
  848.       m_box->he_x1, ( m_box->hel_inc * start ) / INC_ACCURACY,
  849.       m_box->hel_inc, m_box->x_start, x_pos, m_box->hel_x1 );
  850.    ui_wtitle( m_box->window, ui_tbuf );
  851.    ui_wait();
  852. #endif
  853.  
  854.    /* draw the elevator */
  855.  
  856. #ifdef USE_ICONS
  857.    ui_pbmcenter( ui_screen, m_box->hel_x1, m_box->hel_y1, m_box->hel_x2,
  858.       m_box->hel_y2, &ui_elicon );
  859. #else
  860.    ui_fbox( m_box->hel_x1 + EL_OFFSET, m_box->hel_y1 + EL_OFFSET,
  861.       m_box->hel_x2 - EL_OFFSET, m_box->hel_y2 - EL_OFFSET,
  862.       BLACK, SOLID );
  863.    ui_fbox( m_box->hel_x1 + EL_OFFSET + 1,
  864.       m_box->hel_y1 + EL_OFFSET + 1,
  865.       m_box->hel_x2 - ( EL_OFFSET + 1),
  866.       m_box->hel_y2 - (EL_OFFSET + 1),
  867.       m_box->back, SOLID );
  868.    gr_circle( ui_screen,
  869.       m_box->hel_x1 + ( ( m_box->hs_x2 - m_box->he_x2 ) / 2 ),
  870.       m_box->hel_y1 + ( ( m_box->hel_y2 - m_box->hel_y1 ) / 2 ),
  871.       ( m_box->hel_y2 - m_box->hel_y1 ) / 4,
  872.       BLACK, SOLID );
  873.    gr_circle( ui_screen,
  874.       m_box->hel_x1 + ( ( m_box->hs_x2 - m_box->he_x2 ) / 2 ),
  875.       m_box->hel_y1 + ( ( m_box->hel_y2 - m_box->hel_y1 ) / 2 ),
  876.       ( m_box->hel_y2 - m_box->hel_y1 ) / 4,
  877.       m_box->high, GRID );
  878. #endif
  879.  
  880.    }
  881.  
  882. uil_exit( m_box, type )
  883.    struct menu_box *m_box;
  884.    int type;
  885.    {
  886.  
  887.    /* blank the exit button */
  888.  
  889.    if ( type != MENU_PLAIN )
  890.       {
  891. #ifdef USE_ICONS
  892. #else
  893.       ui_fbox( m_box->window->bt_x1, m_box->window->bt_y1,
  894.      m_box->window->bt_x2, m_box->window->bt_y2, BLACK, SOLID );
  895. #endif
  896.       }
  897.  
  898.    /* fill elevators with grid */
  899.  
  900.    if ( type == MENU_SLIDERS )
  901.       {
  902.       if ( m_box->ve_y2 > m_box->ve_y1 )
  903.          {
  904.          ui_fbox( m_box->vs_x1, m_box->ve_y1,
  905.            m_box->vs_x2, m_box->ve_y2, BLACK, SOLID );   /* blank */
  906.          ui_fbox( m_box->vs_x1 + 1, m_box->ve_y1 + 1,
  907.             m_box->vs_x2 - 1, m_box->ve_y2 - 1,
  908.             m_box->back, GRID );
  909.          }
  910.       ui_fbox( m_box->he_x1, m_box->hs_y1,
  911.      m_box->he_x2, m_box->hs_y2, BLACK, SOLID );     /* blank */
  912.       ui_fbox( m_box->he_x1 + 1, m_box->hs_y1,
  913.      m_box->he_x2 - 1, m_box->hs_y2,
  914.      m_box->back, GRID );
  915.       }
  916.  
  917.    }
  918.  
  919. /****************************************************************
  920.  
  921.    ui_event()   Query if keyboard or mouse actions affect
  922.                  a list or icon menu box
  923.  
  924. ****************************************************************/
  925.  
  926. ui_event( m_box, key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest,
  927.    how_far, x_sel, y_sel )
  928.    struct menu_box *m_box;
  929.    int key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest;
  930.    int *how_far, *x_sel, *y_sel;
  931.    {
  932.    register int c, d;
  933.  
  934.    /* if a key is available, simply return it */
  935.  
  936.    if ( key != FALSE )
  937.       {
  938.       return key;
  939.       }
  940.  
  941.    /* else presume that a mouse event has occurred */ 
  942.  
  943.    /* if the destination point is not within the window check to see if
  944.       the source point is */
  945.  
  946.    else if ( uil_bounds( mo_xdest, mo_ydest, m_box->window->x1,
  947.       m_box->window->y1, m_box->window->x2, m_box->window->y2 ) == FALSE )
  948.       {
  949.       if ( uil_bounds( mo_xsrc, mo_ysrc, m_box->window->x1,
  950.          m_box->window->y1, m_box->window->x2, m_box->window->y2 ) == TRUE )
  951.          {
  952.  
  953.          /* test for selection bounds */
  954.  
  955.          for ( c = 0; c < m_box->y_items; ++c )
  956.             {
  957.             for ( d = 0; d < m_box->x_items; ++d )
  958.                {
  959.            if ( uil_bounds( mo_xsrc, mo_ysrc,
  960.                   m_box->i_x1 + ( d * m_box->xsize ),
  961.                   m_box->i_y2 - ( ( c + 1 ) * m_box->ysize ),
  962.                   m_box->i_x1 + ( ( d + 1 ) * m_box->xsize ),
  963.                   m_box->i_y2 - ( c * m_box->ysize ) ) == TRUE )
  964.                   {
  965.                   *y_sel = c;
  966.                   *x_sel = d;
  967.                   return MO_SRC;
  968.                   }
  969.                }
  970.             }
  971.  
  972.          /* selection bounds tests failed */
  973.  
  974.          return FALSE;
  975.          }
  976.       else
  977.          {
  978.          return FALSE;
  979.          }
  980.       } 
  981.    
  982.    /* Check to see if source is within range of the vertical elevator */
  983.  
  984.    else if ( uil_bounds( mo_xsrc, mo_ysrc, m_box->vel_x1, m_box->vel_y1,
  985.       m_box->vel_x2, m_box->vel_y2 ) == TRUE )
  986.       {
  987.       if ( ( mo_ysrc - mo_ydest ) == 0 )
  988.          {
  989.          return FALSE; 
  990.          }
  991.       else if ( ( mo_ysrc - mo_ydest ) > 0 )
  992.          {
  993.          *how_far = (( mo_ysrc - mo_ydest ) 
  994.             * INC_ACCURACY )
  995.             / m_box->vel_inc;
  996.          return MO_DN;
  997.          }
  998.       else
  999.          {
  1000.          *how_far = (( mo_ydest - mo_ysrc ) 
  1001.             * INC_ACCURACY )
  1002.             / m_box->vel_inc;
  1003.          return MO_UP;
  1004.          }
  1005.       }
  1006.  
  1007.    if ( uil_bounds( mo_xsrc, mo_ysrc, m_box->hel_x1, m_box->hel_y1,
  1008.       m_box->hel_x2, m_box->hel_y2 ) == TRUE )
  1009.       {
  1010.       if ( ( mo_xsrc - mo_xdest ) == 0 )
  1011.          {
  1012.          return FALSE;
  1013.          }
  1014.       else if ( ( mo_xsrc - mo_xdest ) > 0 )
  1015.          {
  1016.          *how_far = (( mo_xsrc - mo_xdest ) 
  1017.             * INC_ACCURACY )
  1018.             / m_box->hel_inc;
  1019.          return MO_LEFT;
  1020.          }
  1021.       else
  1022.          {
  1023.          *how_far = (( mo_xdest - mo_xsrc ) 
  1024.             * INC_ACCURACY )
  1025.             / m_box->hel_inc;
  1026.          return MO_RIGHT;
  1027.          }
  1028.       }
  1029.  
  1030.    /* test for exit button bounds */
  1031.  
  1032.    if ( uil_bounds( mo_xdest, mo_ydest, m_box->window->bt_x1, m_box->window->bt_y1,
  1033.       m_box->window->bt_x2, m_box->window->bt_y2 ) == TRUE )
  1034.       {
  1035.       return MO_EXIT;
  1036.       }
  1037.  
  1038.    /* test for up arrow bounds */
  1039.  
  1040.    if ( uil_bounds( mo_xdest, mo_ydest, m_box->vs_x1, m_box->ve_y2,
  1041.       m_box->vs_x2, m_box->vs_y2 ) == TRUE )
  1042.       {
  1043.       *how_far = 1;
  1044.       return MO_UP;
  1045.       }
  1046.  
  1047.    /* test for down arrow bounds */
  1048.  
  1049.    if ( uil_bounds( mo_xdest, mo_ydest, m_box->vs_x1, m_box->vs_y1,
  1050.       m_box->vs_x2, m_box->ve_y1 ) == TRUE )
  1051.       {
  1052.       *how_far = 1;
  1053.       return MO_DN;
  1054.       }
  1055.  
  1056.    /* test for left arrow bounds */
  1057.  
  1058.    if ( uil_bounds( mo_xdest, mo_ydest, m_box->hs_x1, m_box->hs_y1,
  1059.       m_box->he_x1, m_box->hs_y2 ) == TRUE )
  1060.       {
  1061.       *how_far = 1;
  1062.       return MO_LEFT;
  1063.       }
  1064.  
  1065.    /* test for right arrow bounds */
  1066.  
  1067.    if ( uil_bounds( mo_xdest, mo_ydest, m_box->he_x2, m_box->hs_y1,
  1068.       m_box->hs_x2, m_box->hs_y2 ) == TRUE )
  1069.       {
  1070.       *how_far = 1;
  1071.       return MO_RIGHT;
  1072.       }
  1073.  
  1074.    /* test for selection bounds */
  1075.  
  1076.    for ( c = 0; c < m_box->y_items; ++c )
  1077.       {
  1078.       for ( d = 0; d < m_box->x_items; ++d )
  1079.          {
  1080.      if ( uil_bounds( mo_xdest, mo_ydest,
  1081.             m_box->i_x1 + ( d * m_box->xsize ),
  1082.             m_box->i_y2 - ( ( c + 1 ) * m_box->ysize ),
  1083.             m_box->i_x1 + ( ( d + 1 ) * m_box->xsize ),
  1084.             m_box->i_y2 - ( c * m_box->ysize ) ) == TRUE )
  1085.             {
  1086.             *y_sel = c;
  1087.             *x_sel = d;
  1088.             return MO_SEL;
  1089.             }
  1090.          }
  1091.       }
  1092.    }
  1093.  
  1094. /****************************************************************
  1095.  
  1096.    uil_bounds()  See if x and y are within bounds of x1, y1, x2, y2
  1097.  
  1098. ****************************************************************/
  1099.  
  1100. uil_bounds( x, y, x1, y1, x2, y2 )
  1101.    int x, y, x1, y1, x2, y2;
  1102.    {
  1103.     if ( x < x1 )
  1104.       {
  1105.       return FALSE;
  1106.       }
  1107.     if ( x > x2 )
  1108.       {
  1109.       return FALSE;
  1110.       }
  1111.     if ( y < y1 )
  1112.       {
  1113.       return FALSE;
  1114.       }
  1115.     if ( y > y2 )
  1116.       {
  1117.       return FALSE;
  1118.       }
  1119.    return TRUE;
  1120.    }
  1121.  
  1122. /****************************************************************
  1123.  
  1124.    uil_sliders()      Calculate and draw sliders
  1125.                       for menu/icon box
  1126.  
  1127. ****************************************************************/
  1128.  
  1129. uil_sliders( m_box )
  1130.    struct menu_box *m_box;
  1131.    {
  1132.    int midv, midh, toph, both, leftv, rightv;
  1133.    int halfh, halfv, x, y;
  1134.  
  1135.    /* assign sizes to icon area and sliders */
  1136.  
  1137.    x = ui_grwind->fxsize * SL_YSIZE;
  1138.    if ( x > SL_XMAX )
  1139.       {
  1140.       x = SL_XMAX;
  1141.       }
  1142.    y = (( x * gr_pxsize ) * ACC ) / ( gr_pysize * ACC );
  1143.  
  1144. #ifdef OLD_DEBUG
  1145.    sprintf( bw_ebuf, "SL_XMAX = %d; x = %d, y = %d", SL_XMAX, x, y );
  1146.    bw_debug( bw_ebuf );
  1147. #endif
  1148.  
  1149.    m_box->i_x1  = m_box->window->u_x1 + 2;
  1150.    m_box->i_y1  = m_box->window->u_y1 + y;
  1151.    m_box->i_x2  = m_box->window->u_x2 - ( x + 3 );
  1152.    m_box->i_y2  = m_box->window->u_y2 - 1;
  1153.    m_box->vs_x1 = m_box->window->u_x2 - ( x + 1 );
  1154.    m_box->vs_y1 = m_box->i_y1;
  1155.    m_box->vs_x2 = m_box->window->u_x2;
  1156.    m_box->vs_y2 = m_box->window->u_y2 - 1;
  1157.    m_box->hs_x1 = m_box->window->u_x1 + 1;
  1158.    m_box->hs_y1 = m_box->window->u_y1;
  1159.    m_box->hs_x2 = m_box->i_x2;
  1160.    m_box->hs_y2 = m_box->i_y1 - 1;
  1161.    m_box->ve_y1 = m_box->vs_y1 + y;
  1162.    m_box->ve_y2 = m_box->vs_y2 - y;
  1163.    m_box->he_x1 = m_box->window->u_x1 + x;
  1164.    m_box->he_x2 = m_box->hs_x2 - x;
  1165.  
  1166. #ifdef OLD_DEBUG
  1167.                sprintf( bw_ebuf, "made horizontal slider %d %d %d %d", 
  1168.                   m_box->hs_x1, m_box->hs_y1, m_box->hs_x2, m_box->hs_y2 );
  1169.                bw_debug( bw_ebuf );
  1170. #endif
  1171.  
  1172.    /* outline the areas */
  1173.  
  1174.    gr_line( ui_screen, m_box->window->u_x1, m_box->hs_y2,
  1175.       m_box->vs_x2, m_box->hs_y2, m_box->fore, SOLID );
  1176.    --m_box->hs_y2;
  1177.    gr_line( ui_screen, m_box->vs_x1, m_box->hs_y1,
  1178.       m_box->vs_x1, m_box->window->u_y2, m_box->fore, SOLID );
  1179.    ++m_box->vs_x1;
  1180.  
  1181.    /* demarcate arrow areas */
  1182.  
  1183.    gr_line( ui_screen, m_box->he_x1, m_box->hs_y1,
  1184.       m_box->he_x1, m_box->hs_y2, m_box->fore, SOLID );
  1185.    gr_line( ui_screen, m_box->he_x2, m_box->hs_y1,
  1186.       m_box->he_x2, m_box->hs_y2, m_box->fore, SOLID );
  1187.    gr_line( ui_screen, m_box->vs_x1, m_box->ve_y1,
  1188.       m_box->vs_x2, m_box->ve_y1, m_box->fore, SOLID );
  1189.    gr_line( ui_screen, m_box->vs_x1, m_box->ve_y2,
  1190.       m_box->vs_x2, m_box->ve_y2, m_box->fore, SOLID );
  1191.  
  1192.    /* calculate some midpoints */
  1193.  
  1194.    midh   = m_box->hs_y1 + (( m_box->hs_y2 - m_box->hs_y1 ) / 2 );
  1195.    toph   = m_box->hs_y2 - (( m_box->hs_y2 - m_box->hs_y1 ) / 3 );
  1196.    both   = m_box->hs_y1 + (( m_box->hs_y2 - m_box->hs_y1 ) / 3 );
  1197.    midv   = m_box->vs_x1 + (( m_box->vs_x2 - m_box->vs_x1 ) / 2 );
  1198.    leftv  = m_box->vs_x1 + (( m_box->vs_x2 - m_box->vs_x1 ) / 3 );
  1199.    rightv = m_box->vs_x2 - (( m_box->vs_x2 - m_box->vs_x1 ) / 3 );
  1200.  
  1201.    /* left arrow */
  1202.  
  1203.    ui_fbox( m_box->hs_x1, m_box->hs_y1, m_box->he_x1, m_box->hs_y2,
  1204.       m_box->high, SOLID );
  1205. #ifdef USE_ICONS
  1206.    ui_pbmcenter( ui_screen, m_box->hs_x1, m_box->hs_y1, m_box->he_x1, m_box->hs_y2,
  1207.       &ui_lefticn );
  1208. #else
  1209.    halfh  = m_box->hs_x1 + (( m_box->he_x1 - m_box->hs_x1 ) / 2 );
  1210.    uil_arrow(  m_box,
  1211.       m_box->hs_x1, midh,
  1212.       halfh, m_box->hs_y1 + 1,
  1213.       halfh, both,
  1214.       m_box->he_x1, both,
  1215.       m_box->he_x1, toph,
  1216.       halfh, toph,
  1217.       halfh, m_box->hs_y2 - 1,
  1218.       m_box->hs_x1, midh );
  1219.    gr_line( ui_screen, halfh + 1, m_box->hs_y1 + 1,
  1220.       halfh + 1, both, m_box->fore, SOLID );  /* shadow */
  1221.    gr_line( ui_screen, halfh + 1, toph,
  1222.       halfh + 1, m_box->hs_y2 - 1, m_box->fore, SOLID );
  1223.    gr_line( ui_screen, halfh, both - 1,
  1224.       m_box->he_x1, both - 1, m_box->fore, SOLID );
  1225. #endif
  1226.  
  1227.    /* right arrow */
  1228.  
  1229.    ui_fbox( m_box->he_x2, m_box->hs_y1, m_box->hs_x2, m_box->hs_y2,
  1230.       m_box->high, SOLID );
  1231. #ifdef USE_ICONS
  1232.    ui_pbmcenter( ui_screen, m_box->he_x2, m_box->hs_y1, m_box->hs_x2, m_box->hs_y2,
  1233.       &ui_righticn );
  1234. #else
  1235.    halfh  = m_box->he_x2 + (( m_box->hs_x2 - m_box->he_x2 ) / 2 );
  1236.    uil_arrow(  m_box,
  1237.       m_box->hs_x2, midh,
  1238.       halfh, m_box->hs_y1 + 1,
  1239.       halfh, both,
  1240.       m_box->he_x2, both,
  1241.       m_box->he_x2, toph,
  1242.       halfh, toph,
  1243.       halfh, m_box->hs_y2 - 1,
  1244.       m_box->hs_x2, midh );
  1245.    gr_line( ui_screen, halfh, both - 1,
  1246.       m_box->he_x2, both - 1, m_box->fore, SOLID );
  1247.    gr_line( ui_screen, halfh + 1, m_box->hs_y1 + 1,
  1248.       m_box->hs_x2, midh - 1, m_box->fore, SOLID );  /* shadow */
  1249. #endif
  1250.  
  1251.    /* up arrow */
  1252.  
  1253.    ui_fbox( m_box->vs_x1, m_box->ve_y2, m_box->vs_x2, m_box->vs_y2,
  1254.       m_box->high, SOLID );
  1255. #ifdef USE_ICONS
  1256.    ui_pbmcenter( ui_screen, m_box->vs_x1, m_box->ve_y2, m_box->vs_x2, m_box->vs_y2,
  1257.       &ui_upicn );
  1258. #else
  1259.    halfv  = m_box->ve_y2 + (( m_box->vs_y2 - m_box->ve_y2 ) / 2 );
  1260.    uil_arrow(  m_box,
  1261.       midv, m_box->vs_y2,             /* point 1 */
  1262.       m_box->vs_x1 + 1, halfv,            /* point 2 */
  1263.       leftv, halfv,                   /* point 3 */
  1264.       leftv, m_box->ve_y2,            /* point 4 */
  1265.       rightv, m_box->ve_y2,           /* point 5 */
  1266.       rightv, halfv,                  /* point 6 */
  1267.       m_box->vs_x2 - 1, halfv,            /* point 7 */
  1268.       midv, m_box->vs_y2 );           /* point 8 */
  1269.    gr_line( ui_screen, m_box->vs_x1 + 1, halfv - 1,
  1270.       leftv, halfv - 1, m_box->fore, SOLID );
  1271.    gr_line( ui_screen, rightv, halfv - 1,
  1272.       m_box->vs_x2 - 1, halfv - 1, m_box->fore, SOLID );
  1273.    gr_line( ui_screen, rightv + 1, m_box->ve_y2,
  1274.       rightv + 1, halfv, m_box->fore, SOLID );  /* shadow */
  1275. #endif
  1276.  
  1277.    /* down arrow */
  1278.  
  1279.    ui_fbox( m_box->vs_x1, m_box->vs_y1, m_box->vs_x2, m_box->ve_y1,
  1280.       m_box->high, SOLID );
  1281. #ifdef USE_ICONS
  1282.    ui_pbmcenter( ui_screen, m_box->vs_x1, m_box->vs_y1, m_box->vs_x2, m_box->ve_y1,
  1283.       &ui_downicn );
  1284. #else
  1285.    halfv  = m_box->vs_y1 + (( m_box->ve_y1 - m_box->vs_y1 ) / 2 );
  1286.    uil_arrow(  m_box,
  1287.       midv, m_box->vs_y1,             /* point 1 */
  1288.       m_box->vs_x1 + 1, halfv,            /* point 2 */
  1289.       leftv, halfv,                   /* point 3 */
  1290.       leftv, m_box->ve_y1,            /* point 4 */
  1291.       rightv, m_box->ve_y1,           /* point 5 */
  1292.       rightv, halfv,                  /* point 6 */
  1293.       m_box->vs_x2 - 1, halfv,            /* point 7 */
  1294.       midv, m_box->vs_y1 );           /* point 8 */
  1295.    gr_line( ui_screen, rightv + 1, halfv,
  1296.       rightv + 1, m_box->ve_y1, m_box->fore, SOLID );
  1297.    gr_line( ui_screen, midv + 1, m_box->vs_y1,
  1298.       m_box->vs_x2 - 1, halfv - 1, m_box->fore, SOLID );  /* shadow */
  1299. #endif
  1300.  
  1301.    /* blank elevator areas with grid */
  1302.  
  1303. #ifdef OLD_DEBUG
  1304.                sprintf( bw_ebuf, "draw horizontal slider %d %d %d %d", 
  1305.                   m_box->hs_x1, m_box->hs_y1, m_box->hs_x2, m_box->hs_y2 );
  1306.                bw_debug( bw_ebuf );
  1307. #endif
  1308.  
  1309.    if ( m_box->hs_y2 > m_box->hs_y1 )
  1310.       {
  1311. /*           gr_rectangle( ui_screen, m_box->he_x1, m_box->hs_y1,
  1312.          m_box->he_x2, m_box->hs_y2, m_box->fore, HOLLOW ); */
  1313.       gr_rectangle( ui_screen, m_box->he_x1 + 1, m_box->hs_y1,
  1314.          m_box->he_x2 - 1, m_box->hs_y2, m_box->fore, GRID );
  1315. #ifdef OLD_DEBUG
  1316.                sprintf( bw_ebuf, "made horizontal slider %d %d %d %d", 
  1317.                   m_box->hs_x1, m_box->hs_y1, m_box->hs_x2, m_box->hs_y2 );
  1318.                bw_debug( bw_ebuf );
  1319. #endif
  1320.       }
  1321.       
  1322.    if ( m_box->ve_y2 > m_box->ve_y1 )
  1323.       {
  1324.       gr_rectangle( ui_screen, m_box->vs_x1, m_box->ve_y1,
  1325.          m_box->vs_x2, m_box->ve_y2, m_box->fore, HOLLOW );
  1326.       gr_rectangle( ui_screen, m_box->vs_x1 + 1, m_box->ve_y1 + 1,
  1327.          m_box->vs_x2 - 1, m_box->ve_y2 - 1, m_box->fore, GRID );
  1328.       }
  1329.    }
  1330.  
  1331.  
  1332. /****************************************************************
  1333.  
  1334.    uil_arrow()  Draw an arrow for the slider box
  1335.  
  1336. ****************************************************************/
  1337.  
  1338. uil_arrow( m_box,
  1339.    x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8 )
  1340.    struct menu_box *m_box;
  1341.    int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8;
  1342.    {
  1343.    gr_line( ui_screen, x1, y1, x2, y2, m_box->fore, SOLID );
  1344.    gr_line( ui_screen, x2, y2, x3, y3, m_box->fore, SOLID );
  1345.    gr_line( ui_screen, x3, y3, x4, y4, m_box->fore, SOLID );
  1346.    gr_line( ui_screen, x4, y4, x5, y5, m_box->fore, SOLID );
  1347.    gr_line( ui_screen, x5, y5, x6, y6, m_box->fore, SOLID );
  1348.    gr_line( ui_screen, x6, y6, x7, y7, m_box->fore, SOLID );
  1349.    gr_line( ui_screen, x7, y7, x8, y8, m_box->fore, SOLID );
  1350.    }
  1351.  
  1352. /****************************************************************
  1353.  
  1354.    uil_plain()      Calculate sizes
  1355.           for plain menu box
  1356.  
  1357. ****************************************************************/
  1358.  
  1359. uil_plain( m_box )
  1360.    struct menu_box *m_box;
  1361.    {
  1362.  
  1363.    /* assign sizes to icon area */
  1364.  
  1365.    m_box->i_x1  = m_box->window->u_x1 + 2;
  1366.    m_box->i_y1  = m_box->window->u_y1;
  1367.    m_box->i_x2  = m_box->window->u_x2 - 2;
  1368.    m_box->i_y2  = m_box->window->u_y2 - 1;
  1369.    m_box->vs_x1 = 1;
  1370.    m_box->vs_y1 = 1;
  1371.    m_box->vs_x2 = 1;
  1372.    m_box->vs_y2 = 1;
  1373.    m_box->hs_x1 = 1;
  1374.    m_box->hs_y1 = 1;
  1375.    m_box->hs_x2 = 1;
  1376.    m_box->hs_y2 = 1;
  1377.    m_box->ve_y1 = 1;
  1378.    m_box->ve_y2 = 1;
  1379.    m_box->he_x1 = 1;
  1380.    m_box->he_x2 = 1;
  1381.    }
  1382.  
  1383.  
  1384.